package beans.number;

import java.util.HashSet;
import java.util.Set;

import beans.exception.InvalidNumberException;

/**
 * 功能数字归类器1.0
 * 
 * @author beanstao@gmail.com
 * 
 */
public class Classifier
{

	private final Set<Integer> _factors;
	private final int _number;

	public Classifier(int number) throws InvalidNumberException
	{
		if (number < 1)
			throw new InvalidNumberException("Can't classify negative numbers");
		_number = number;
		_factors = new HashSet<Integer>();
		_factors.add(1);
		_factors.add(_number);
	}

	private boolean isFactor(int factor)
	{
		return _number % factor == 0;
	}

	public Set<Integer> getFactors()
	{
		return _factors;
	}

	/**
	 * 整除因子总是以成对的形式被获取。<br>
	 * 例如，如果这个数是16，当我采集的因子为2时，我就能得到另一个因子为8，因为8x2=16。<br>
	 * 如果我获得的因子是成对的，那么我只需要去检查那些有平方根的数，这就是calculateFactors()方法所做的事情。
	 */
	private void calculateFactors()
	{
		for (int i = 1; i <= Math.sqrt(_number) + 1; i++)
		{
			if (isFactor(i))
			{
				addFactor(i);
			}
		}
	}

	/**
	 * 整除因子总是以成对的形式被获取。
	 * 
	 * @param factor
	 */
	private void addFactor(int factor)
	{
		_factors.add(factor);
		_factors.add(_number / factor);
	}

	private int sumOfFactors()
	{
		calculateFactors();
		int sum = 0;
		for (int i : _factors)
			sum += i;
		return sum;
	}

	public boolean isPerfect()
	{
		return sumOfFactors() - _number == _number;
	}

	public boolean isAbundant()
	{
		return sumOfFactors() - _number > _number;
	}

	public boolean isDeficient()
	{
		return sumOfFactors() - _number < _number;
	}

	public static boolean isPerfect(int number) throws InvalidNumberException
	{
		return new Classifier(number).isPerfect();
	}

	public static void main(String[] args)
	{
		try
		{
			Classifier c = new Classifier(10);
			c.calculateFactors();
			Set<Integer> set = c.getFactors();
			for (Integer integer : set)
			{
				System.out.println(integer);
			}
		}
		catch (InvalidNumberException e)
		{
			e.printStackTrace();
		}

	}

}
